package lex.profile.ui.tree;

import java.util.Enumeration;

import javax.swing.tree.TreeNode;

import lex.profile.utils.StringUtils;

import org.lex.utils.collections.ArrayIterator;

import com.vladium.utils.IObjectProfileNode;
import com.vladium.utils.ObjectProfiler;

public class ProfileTreeUtils
{
	public static TreeNode createProfileTree( Object obj )
	{
		IObjectProfileNode profile = ObjectProfiler.profile( obj );
		return new ProfileTreeNode( profile );
	}

	private static class ProfileTreeNode implements TreeNode
	{
		private final IObjectProfileNode node;
		private final ProfileTreeNode[] children;
		private ProfileTreeNode parent;

		public ProfileTreeNode( IObjectProfileNode node )
		{
			this.node = node;
			this.parent = null;
			IObjectProfileNode[] nodes = node.children();
			int nodeCount = nodes.length;
			if( null != node.shell() )
				nodeCount++;
			this.children = new ProfileTreeNode[nodeCount];
			for( int i = 0; i < nodes.length; i++ )
			{
				children[i] = new ProfileTreeNode( nodes[i] );
				children[i].parent = this;
			}
			if( null != node.shell() )
				this.children[nodeCount-1] = new ProfileTreeNode( node.shell() );
		}

		@Override
		public Enumeration<ProfileTreeNode> children()
		{
			return new ArrayIterator<ProfileTreeNode>( children );
		}

		@Override
		public boolean getAllowsChildren()
		{
			return true;
		}

		@Override
		public ProfileTreeNode getChildAt( int index )
		{
			return children[index];
		}

		@Override
		public int getChildCount()
		{
			return children.length;
		}

		@Override
		public int getIndex( TreeNode node )
		{
			return org.lex.utils.Arrays.firstReference( children, node );
		}

		@Override
		public ProfileTreeNode getParent()
		{
			return this.parent;
		}

		@Override
		public boolean isLeaf()
		{
			return 0 == this.children.length;
		}

		@Override
		public String toString()
		{
			StringBuilder buf = new StringBuilder();
			if( null != this.node )
			{
				buf.append( node.name() );
				if( null != node.object() )
				{
					buf.append( " {" );
					buf.append( StringUtils.toString( node.object().getClass() ) );
					buf.append( "}" );
				}
				buf.append( " ref:" ).append( node.refcount() );
			}
			else
			{
				buf.append( "(null)" );
			}
			return buf.toString();
		}
	}
}
